
import logging

from runtime.task import *

class ShowSpacesTask(Task):
    """
    This task is a daemon task. It processes requests from 
    httpserver::RequestHandler and return Spaces resources.
    """
        
    def cb_start(self, method, uri, new_uri, result, context, **kwargs):
        """This function is called when the task starts. 
        
        :param method: <class> or <type>
        :param uri: The task Uri.
        :param new_uri: <class> or <type>
        :param result: <class> or <type>
        :param context: <class> or <type>
        :param kwargs: <class> or <type>
        """
        
        self.logger.log(logging.DEBUG, "***************** uri (%s), new_uri (%s)" % (uri, new_uri))
        
        # All 'put' messages to this task are interpreted as requests for Spaces Resources.
        #
        self.spaces_context.process(uri.add("listen"), put='put_resource')
        
    def cb_stop(self, method, uri, res, result, context, **kwargs):
        """This function will stop any listeners still running.
        
        :param method: <class> or <type>
        :param uri: The task Uri.
        :param res: <class> or <type>
        :param result: <class> or <type>
        :param context: <class> or <type>
        :param kwargs: <class> or <type>
        """
        
        self.logger.log(logging.DEBUG, "method (%s), uri (%s)" % (method, uri))
    
    def put_resource(self, method, uri, res, result, context, **kwargs):
        """This function retrieves the Spaces Resource at the Uri in the Resource
        at the argument Uri.
        
        :param method: <class> or <type>
        :param uri: The task Uri.
        :param res: Resource
        :param result: <class> or <type>
        :param context: <class> or <type>
        :param kwargs: <class> or <type>
        """
        
        self.logger.log(logging.DEBUG, "uri (%s), res (%s), result (%s)" % (str(uri), res, result))
        
        requested_uri = res.uri
        output_rs = Resource()
        
        # remove leading '/', if any...
        #
        if (requested_uri.match('/')):
            requested_uri = Uri(str(requested_uri)[1:])
        
        if (len(str(requested_uri)) == 0):
            # return namespaces
            #
            output_rs.namespaces_dict = self.spaces.get_bindings()
        else:
            # see if spaces has the requested Uri
            #
            spaces_rs = self.spaces_context.get(requested_uri)
            if (spaces_rs is not None):
                output_rs.resource_dict = spaces_rs.get_vars()
            else:
                # return all Uris, if any, under the requested Uri.
                #
                uri_list = self.spaces_context.dump(requested_uri)
                output_rs.resources_list = uri_list
        
        # Note: The convention for returning Resources from a server task (like 
        #       this) to clients is:
        #
        #       1. create a Uri based on the server task's Uri, appended with the
        #          parts:
        #          - "requests"
        #          - <uuid>
        #          - "response"
        #       2. put() the output Resource to Spaces using the Uri.
        #       3. return a copy of the Uri to the client, with only the first 2 
        #          parts, for them to request the result Resource from Spaces.
        #          The client will get_wait() on:
        #
        #          <response_uri>.add("response")
        # 
        #       A consequence of this is that the server task CANNOT process 
        #       requests sent to "<task_uri>.collection(True)" because they will
        #       process the response Resources. (Actually the server task will 
        #       block on Spaces.put() because the same task is waiting on the Uri.)
        #
        response_uri = self.spaces_context.uri(self.task_uri).requests.add(str(self.spaces_context.uuid()))
        self.spaces_context.put(response_uri.response, output_rs)
        return (True, response_uri.uri_copy())